package net.oschina.archx.spring.datasource;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 通过AOP切换数据源
 *
 * <p>
 *     本切面配置不生效
 *
 *     Spring的事物管理是和数据源绑定在一起的，如果事物管理配置在Service层那么数据源的切换就要在Controller层
 * </p>
 *
 * Created by Archx on 2015/6/22 0022.
 */
@Aspect
public class DBContextAspect {

    final Logger log = LoggerFactory.getLogger(this.getClass());

    final String localDatasource = "localDataSource";
    final String remoteDatasource = "remoteDataSource";

    @Pointcut(value = "execution( * net.oschina.archx.spring.service..*+.*Local(..))")
    public void localPointcut(){};

    @Before(value = "localPointcut()")
    public void beforeLocalAdvice(){
        DBContextHolder.setDbContext(localDatasource);
        log.info("切换到本地数据源 {}", localDatasource);
    }


    @Pointcut(value = "execution( * net.oschina.archx.spring.service..*+.*Remote(..))")
    public void remotePointcut(){};

    @Before(value = "remotePointcut()")
    public void beforeRemoteAdvice(){
        DBContextHolder.setDbContext(remoteDatasource);
        log.info("切换到远程数据源 {}", remoteDatasource);
    }

    @AfterReturning(value = "localPointcut() || remotePointcut()")
    public void afterAdvice() {
        DBContextHolder.removeDbContext();
        log.info("恢复默认数据源");
    }
}
